| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677 |
- 'use client';
- import { useEffect, useState } from 'react';
- import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
- import { faCoins } from '@fortawesome/free-solid-svg-icons';
- import './youtube-chat-iframe.scss';
- type Props = {
- videoId: string|null;
- onDonate?: () => void;
- };
- /**
- * YouTube Live Chat 임베드 컴포넌트.
- *
- * - URL 형식: https://www.youtube.com/live_chat?v={VIDEO_ID}&embed_domain={HOST}
- * - embed_domain 은 NEXT_PUBLIC_EMBED_DOMAIN 환경변수 사용 (호스트만, 프로토콜/포트 제외)
- * - 라이브 중일 때만 정상 표시 (videoId 가 있어야 함)
- * - 비라이브 또는 환경변수 미설정 시 fallback UI
- *
- * Quota 비용: 0 — YouTube 자체 인프라 사용, dpot 의 quota 소비 없음.
- */
- export default function YouTubeChatIframe({ videoId, onDonate }: Props)
- {
- const [embedDomain, setEmbedDomain] = useState<string|null>(null);
- useEffect(() => {
- // SSR 시점에는 process.env 가 없을 수 있어 마운트 후 해석
- const envDomain = process.env.NEXT_PUBLIC_EMBED_DOMAIN;
- if (envDomain) {
- setEmbedDomain(envDomain);
- return;
- }
- // fallback: 현재 호스트 (개발 환경 보조)
- if (typeof window !== 'undefined') {
- setEmbedDomain(window.location.hostname);
- }
- }, []);
- const chatUrl = videoId && embedDomain
- ? `https://www.youtube.com/live_chat?v=${encodeURIComponent(videoId)}&embed_domain=${encodeURIComponent(embedDomain)}`
- : null;
- return (
- <div className="yt-chat">
- {chatUrl ? (
- <iframe
- className="yt-chat__iframe"
- src={chatUrl}
- title="YouTube Live Chat"
- allow="autoplay"
- sandbox="allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox allow-forms"
- />
- ) : (
- <div className="yt-chat__offline">
- <p className="yt-chat__offline-title">현재 라이브 방송이 아닙니다</p>
- <p className="yt-chat__offline-desc">라이브 방송이 시작되면 채팅에 참여할 수 있어요.</p>
- </div>
- )}
- {onDonate && (
- <div className="yt-chat__footer">
- <button
- type="button"
- className="yt-chat__donate-btn"
- onClick={onDonate}
- aria-label="후원하기"
- >
- <FontAwesomeIcon icon={faCoins} />
- <span>후원하기</span>
- </button>
- </div>
- )}
- </div>
- );
- }
|